#include "threadPool.h"

#include <ctype.h>
static char *file_type(mode_t md)
{
	if (S_ISREG(md))
	{
		return "-";
	}
	else if (S_ISDIR(md))
	{
		return "d";
	}
	else if (S_ISFIFO(md))
	{
		return "p";
	}
	else
	{
		return "o";
	}
}
int myChdir(threadPool_t *pthreadPool)
{
	char dir[128] = "";
	printf("str = %s\n", pthreadPool->buf);
	printf("before cd,working directory: %s\n", getcwd(NULL, 0));
	int ret;
    int cFlag=0;
	ret = chdir(pthreadPool->buf); // 去/tmp
	if (-1 == ret)
	{
		perror("chdir");
        send(pthreadPool->netfd, &cFlag, sizeof(int), 0);
		return -1;
        
	}
    cFlag=1;
    send(pthreadPool->netfd, &cFlag, sizeof(int), 0);
    memset(dir,0,sizeof(dir));
	getcwd(dir, 128);
	int len = strlen(dir);
	send(pthreadPool->netfd, &len, sizeof(int), 0);
	sendn(pthreadPool->netfd, dir, strlen(dir));
	printf("after cd,working directory: %s\n", getcwd(NULL, 0));
	return 0;
}
int pwd(threadPool_t *pthreadPool)
{
	bzero(pthreadPool->buf, BUF_SIZE);
	getcwd(pthreadPool->buf, BUF_SIZE);
	int len = strlen(pthreadPool->buf);
	send(pthreadPool->netfd, &len, sizeof(int), 0);
	sendn(pthreadPool->netfd, pthreadPool->buf, len);
	return 0;
}
int ls(threadPool_t *pthreadPool)
{
	DIR *pdir = opendir("./");
	if (pdir == NULL)
	{
		int flag = -1;
		send(pthreadPool->netfd, &flag, sizeof(int), 0);
	}
	else
	{
		struct dirent *mydir;
		int len;
		while ((mydir = readdir(pdir)) != NULL) // 读取目录
		{
			if (strncmp(mydir->d_name, ".", 1) == 0 || strncmp(mydir->d_name, "..", 2) == 0)
			{
				continue;
			}
			struct stat mystat;
			bzero(&mystat, sizeof(stat));
			stat(mydir->d_name, &mystat); // 获取某个文件的信息
			bzero(pthreadPool->buf, 1024);
			sprintf(pthreadPool->buf, "%-2s%-20s %10ldB", file_type(mystat.st_mode), mydir->d_name, mystat.st_size);
			len = strlen(pthreadPool->buf);
			send(pthreadPool->netfd, &len, sizeof(int), 0); // 发送数据给客户端
			sendn(pthreadPool->netfd, pthreadPool->buf, len);
		}
		len = 0;
		send(pthreadPool->netfd, &len, sizeof(int), 0);
	}
}
int reMove(threadPool_t *pthreadPool)
{
	char buf[128]="";
	int len;
	if (unlink(pthreadPool->buf) == -1)
	{
		perror("Failed to delete file");
		strcpy(buf, "Failed to delete file\n");
		len=strlen(buf);
		send(pthreadPool->netfd, &len, sizeof(int), 0);
		sendn(pthreadPool->netfd,buf,len);
	}
	else
	{
		strcpy(buf, "file removed success\n");
		len=strlen(buf);
		send(pthreadPool->netfd, &len, sizeof(int), 0);
		sendn(pthreadPool->netfd,buf,len);
	}
}

int recvn(int netfd, void *buf, int length)
{
	int total = 0; // 存储已经读取了多少个字节
	int ret;
	char *p = (char *)buf; // 一个char一个字节
	while (total < length)
	{
		ret = recv(netfd, p + total, length - total, 0);
		total += ret;
	}
}
int sendn(int fd_send, char *send_buf, int len)
{
	int sum = 0;
	int nsend;
	while (sum < len)
	{
		nsend = send(fd_send, send_buf + sum, len - sum, 0);
		sum += nsend;
	}
	return sum;
}
int getSalt(usraddr *usr)
{
	MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    char *sql = "select * from user";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    MYSQL_ROW row; 
    while((row = mysql_fetch_row(result)) != NULL){
        // 不断地从结果中取出一行
       if(strcmp(usr->usrAddr,row[0])==0){
			memset(usr->pwd,0,sizeof(pwd));
			strcpy(usr->pwd,row[1]);
	   }
    }
    mysql_free_result(result);//释放结果的内存
    mysql_close(mysql);// 释放连接资源
}
char* current_time() {
    time_t now = time(NULL);
    return ctime(&now);
}
void log_INFO(char* msg){
	syslog(LOG_INFO, "[%s] %s", current_time(), msg);
}
void log_ERROR(char* msg){
	syslog(LOG_INFO, "[%s] %s", current_time(), msg);
}
int md5(char *str,unsigned char *md){
    int fd = open(str, O_RDWR);
    MD5_CTX c;
    MD5_Init(&c);
    char buf[4096];
    while(1){
        bzero(buf,4096);
        ssize_t ret = read(fd,buf,4096);
        if(ret == 0){
            break;
        }
        MD5_Update(&c,buf,ret);
    }
    unsigned char MD[16]={0};
    MD5_Final(MD,&c);
	memcpy(md, MD, sizeof(MD));
    for(int i = 0; i < 16;++i){
        printf("%02x", MD[i]);
    }
    printf("\n");
	return 0;
}

int usrExist(usraddr usr){
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
	char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    char *sql = "select * from user";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    MYSQL_ROW row; 
    while((row = mysql_fetch_row(result)) != NULL){
        // 不断地从结果中取出一行
			// 一行的本质，实际上是一个字符串数组
			// 有用户，密码正确 0
			// 有用户，密码错误，重新输入密码 1
			// 无用户，注册用户 2
			if(strcmp(usr.usrAddr,row[0])==0){
				return 1;
			}
	}
	mysql_free_result(result);
	mysql_close(mysql);
	return 0;
}
int checkUsr(usraddr usr){
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
	char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    char *sql = "select * from user";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    MYSQL_ROW row; 
    while((row = mysql_fetch_row(result)) != NULL){
        // 不断地从结果中取出一行
			// 一行的本质，实际上是一个字符串数组
			// 有用户，密码正确 0
			// 有用户，密码错误，重新输入密码 1
			// 无用户，注册用户 2
			if(strcmp(usr.usrAddr,row[0])==0){
				char encryptedStr[50];
				if(strcmp(usr.pwd,row[2])==0){
					mysql_free_result(result); // 释放结果的内存
					mysql_close(mysql);		   // 释放连接资源
					return 0;
				}
				else{
					mysql_free_result(result); 
					mysql_close(mysql);
					return 1;
				}
			}
	}
	mysql_free_result(result);
	mysql_close(mysql);
	return 2;
}
void generateStr(char *str, int len)
{
    int i, flag;
    srand(time(NULL));
    for (i = 0; i < len; i++)
    {
        flag = rand() % 3;
        switch (flag)
        {
        case 0:
            str[i] = rand() % 26 + 'a';
            break;
        case 1:
            str[i] = rand() % 26 + 'A';
            break;
        case 2:
            str[i] = rand() % 10 + '0';
            break;
        }
    }
    str[len] = '\0';
}
int usrReg(usraddr usr){
	char str[21]={0};
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
	printf("%s\n",usr.usrAddr);
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
	generateStr(str, 21);
	char sql[100];
	char encryptedStr[50];
	strcpy(encryptedStr, crypt(usr.pwd, str));
	sprintf(sql, "INSERT INTO user VALUES('%s','%s','%s')", usr.usrAddr, str, encryptedStr);

	int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    mysql_close(mysql);// 释放连接资源
}
int fileReg(usraddr usr){
    fileTrain file;
    strcpy(file.filename,"root");
    strcpy(file.usr,usr.usrAddr);
    strcpy(file.type,"d");
    strcpy(file.MD5,"NULL");
    printf("filename = %s, usr = %s, type = %s\n", file.filename, file.usr, file.type);

    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
     // 打开文件
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
	char sql[256];
    snprintf(sql, sizeof(sql), "INSERT INTO fileFolder (id, filename, usr, parent, type, MD5) VALUES (NULL, '%s', '%s', %d, '%s', '%s')", file.filename, file.usr, -1, file.type, file.MD5);

	int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    mysql_close(mysql);// 释放连接资源
}

int selectUsr(){
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    char *sql = "select * from user";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    printf("total rows :%lu\n", mysql_num_rows(result)); //结果总共有多少行
    MYSQL_ROW row; 
    while((row = mysql_fetch_row(result)) != NULL){
        // 不断地从结果中取出一行
        for(int i = 0; i < mysql_num_fields(result); ++i){
            // 一行的本质，实际上是一个字符串数组
            printf("%s    ", row[i]);
        }
        printf("\n");
    }
    mysql_free_result(result);//释放结果的内存
    mysql_close(mysql);// 释放连接资源
}
int getUsrid(fileTrain file){
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    char sql[100];
    sprintf(sql, "select * from fileFolder where usr = '%s'", file.usr);
    int qret = mysql_query(mysql, sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    MYSQL_ROW row; 
    if((row = mysql_fetch_row(result)) != NULL){
        return atoi(row[0]);
    }
    mysql_free_result(result);//释放结果的内存
    mysql_close(mysql);// 释放连接资源
    return -1;
}
char **split_words(char *str, int *count)
{
    int i, j, k;
    char **words = NULL;
    char *word = NULL;
    *count = 0;
    i = j = 0;
    while (str[i])
    {
        while (isspace(str[i]))
            i++; // skip leading spaces
        j = i;
        while (!isspace(str[j]) && str[j])
            j++; // find end of word
        if (j > i)
        {                                              // if word found
            word = malloc(sizeof(char) * (j - i + 1)); // allocate memory for word
            if (!word)
            { // check if allocation failed
                for (k = 0; k < *count; k++)
                    free(words[k]); // free memory allocated for previous words
                free(words);        // free memory allocated for word pointers
                *count = 0;         // reset count
                return NULL;        // return NULL
            }
            strncpy(word, str + i, j - i);                     // copy word
            word[j - i] = '\0';                                // add null terminator
            (*count)++;                                        // increment count
            words = realloc(words, sizeof(char *) * (*count)); // allocate memory for new word pointer
            words[*count - 1] = word;                          // add word pointer to array
        }
        i = j + 1; // move to next word
    }
    return words;
}
int makeWorker(threadPool_t *pthreadPool)
{
    for (int i = 0; i < pthreadPool->threadNum; ++i)
    {
        pthread_create(pthreadPool->tidArr + i, NULL, threadFunc, pthreadPool);
    }
}
void cleanMutex(void *pargs)
{
    threadPool_t *pthreadPool = (threadPool_t *)pargs;
    pthread_mutex_unlock(&pthreadPool->taskQueue.mutex);
}


//产生随机数，盐值
void generateFile(char *str, int len)
{
    int i, flag;
    srand(time(NULL));
    for (i = 0; i < len; i++)
    {
        flag = rand() % 3;
        switch (flag)
        {
        case 0:
            str[i] = rand() % 26 + 'a';
            break;
        case 1:
            str[i] = rand() % 26 + 'A';
            break;
        case 2:
            str[i] = rand() % 10 + '0';
            break;
        }
    }
    str[len] = '\0';
}
void printFileTrain(fileTrain f) {
    printf("dataLen: %d\n", f.dataLen);
    printf("filename: %s\n", f.filename);
    printf("usr: %s\n", f.usr);
    printf("parent: %d\n", f.parent);
    printf("type: %s\n", f.type);
    printf("MD5:%s\n",f.MD5);
}
void InsertFile(fileTrain file) {
    MYSQL *mysql = mysql_init(NULL); // 建立连接资源

    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL *ret = mysql_real_connect(mysql, host, user, password, database, 0, NULL, 0);
    if (ret == NULL) { // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return;
    }

    // 查询是否已经存在该记录
    char query[200];
    sprintf(query, "SELECT * FROM fileFolder WHERE filename='%s' AND usr='%s' AND parent=%d AND type='%s' AND MD5='%s'", file.filename, file.usr, file.parent, file.type, file.MD5);
    int qret = mysql_query(mysql, query);
    if (qret != 0) {
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        mysql_close(mysql); // 释放连接资源
        return;
    }

    MYSQL_RES *result = mysql_store_result(mysql);
    if (mysql_num_rows(result) > 0) { // 如果已存在该记录，直接返回
        mysql_free_result(result);
        mysql_close(mysql); // 释放连接资源
        return;
    }
    mysql_free_result(result);

    // 插入新记录
    sprintf(query, "INSERT INTO fileFolder (filename, usr, parent, type, MD5) VALUES ('%s', '%s', %d, '%s', '%s')", file.filename, file.usr, file.parent, file.type, file.MD5);
    qret = mysql_query(mysql, query);
    if (qret != 0) {
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        mysql_close(mysql); // 释放连接资源
        return;
    }

    mysql_close(mysql); // 释放连接资源
}


int selectFile(){
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    char *sql = "select * from fileFolder";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return -1;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    printf("%-5s\t%-10s\t%-10s\t%-5s\t%-1s\t%-40s\n", "ID", "Name", "Owner", "Size", "Type", "MD5"); // 打印表头
    MYSQL_ROW row; 
    while((row = mysql_fetch_row(result)) != NULL){
        // 不断地从结果中取出一行
        printf("%-5s\t%-10s\t%-10s\t%-5s\t%-1s\t%-40s\n", row[0], row[1], row[2], row[3], row[4], row[5]);
    }
    mysql_free_result(result);//释放结果的内存
    mysql_close(mysql);// 释放连接资源
    return 0;
}
void selectFolder(char* usr) {
    MYSQL * mysql = mysql_init(NULL); // 建立连接资源
    // 连接到数据库
    char *host = "localhost";
    char *user = "root";
    char *password = "123";// 自定义
    char *database = "ftpUsr";
    MYSQL * ret = mysql_real_connect(mysql,host,user,password,database,0,NULL,0);
    if(ret == NULL){ // ret为NULL 报错
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return;
    }
    char sql[1024];
    sprintf(sql, "select * from fileFolder where usr='%s' and type='f' and parent in (select id from fileFolder where usr='%s')", usr, usr);
    int qret = mysql_query(mysql, sql);
    if(qret != 0){
        fprintf(stderr, "error:%s\n", mysql_error(mysql));
        return;
    }
    // 取出结果的表格 MYSQL_RES
    MYSQL_RES * result = mysql_store_result(mysql);
    printf("total rows :%lu\n", mysql_num_rows(result)); //结果总共有多少行
    MYSQL_ROW row; 
    while((row = mysql_fetch_row(result)) != NULL){
        // 不断地从结果中取出一行
        for(int i = 0; i < mysql_num_fields(result); ++i){
            // 一行的本质，实际上是一个字符串数组
            printf("%s    ", row[i]);
        }
        printf("\n");
    }
    mysql_free_result(result);//释放结果的内存
    mysql_close(mysql);// 释放连接资源
}


